package com.kingmed.kmss.framework.feign.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.kingmed.kmss.common.annotation.DictAnnotation;
import com.kingmed.kmss.common.utils.AppContextUtil;
import com.kingmed.kmss.common.utils.StringUtils;
import com.kingmed.kmss.framework.feign.client.dict.DictFeignServiceFacade;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * Description: 字典填充工具类
 * </p>
 *
 **/
@Slf4j
public class DictFillUtils {

    private static final String DIC_KEY = "dictKey";
    private static final String DIC_VALUE = "dictValue";

    @SuppressWarnings("unchecked")
	public static <T> T fillDict(T obj){
        if (ObjectUtil.isNull(obj)) {
            return obj;
        }
    	return (T) fillDict(Arrays.asList(obj)).get(0);
    }
    public static List fillDict(List dataList){
        if(!CollectionUtils.isEmpty(dataList)){
            Class rowClass = dataList.get(0).getClass();
            Map<Field, DictAnnotation> dictAnnoMap = getDictAnnotaion(rowClass);
            if(dictAnnoMap.size() > 0){
                //填充名称字段
                fillNameField(dataList, dictAnnoMap);
            }
        }
        return dataList;
    }

    /**
     *
     * @param clazz
     * @return
     */
    public static Map<Field, DictAnnotation> getDictAnnotaion(Class clazz){
        Map<Field, DictAnnotation> dictAnnoMap = new LinkedHashMap<>();
        while (clazz !=null) {
            Field[] fs = clazz.getDeclaredFields();
            for (Field feild : fs) {
                // 过滤没有数@Dict注解
                if (!feild.isAnnotationPresent(DictAnnotation.class)) {
                    continue;
                }
                DictAnnotation dict = feild.getAnnotation(DictAnnotation.class);
                dictAnnoMap.put(feild, dict);
            }
            clazz = clazz.getSuperclass();
        }

        return dictAnnoMap;
    }

    /**
     * 根据code与value 值取相关name 字段
     * @param dataList
     * @param dictAnnoMap
     * @return
     */
    private static void  fillNameField(List dataList, Map<Field, DictAnnotation> dictAnnoMap){
        dictAnnoMap.forEach((k,v)->{
            Field f = k;
            DictAnnotation dict = v;
            List<String> codeList = new ArrayList<>();
            for (Object data : dataList) {
                BeanWrapper beanWrapper = new BeanWrapperImpl(data);
                if(data != null && beanWrapper.isReadableProperty(f.getName())
                        && beanWrapper.getPropertyValue(f.getName()) != null){
                    codeList.add(ObjectUtil.toString(beanWrapper.getPropertyValue(f.getName())));
                }
            }
            // 去重codeList
            codeList = codeList.stream().distinct().collect(Collectors.toList());
            // 字典code字段有值，需翻译，填充相关name属性
            if(!codeList.isEmpty()){
                //获取字典数据
                String typeCode = dict.dicTypeCode();
                String contrastText = dict.contrastText();
                if(StringUtils.isEmpty(contrastText)){
                    contrastText = f.getName();
                }

                List<String> fillTextList = Arrays.asList(dict.fillText().split(","));
                List<String> contrastFillTextList = new ArrayList<>();
                if(StringUtils.isNotEmpty(dict.contrastFillText())) {
                    contrastFillTextList = Arrays.asList(dict.contrastFillText().split(","));
                }

                //如果为字典
                if(StringUtils.isNotEmpty(typeCode)){
                    codeList = new ArrayList<>();
                    codeList.add(typeCode);
                    contrastText = DIC_KEY;
                    contrastFillTextList = new ArrayList<>();
                    for(String e:fillTextList) {
                        contrastFillTextList.add(DIC_VALUE);
                    }
                }

                //查看是否设置了默认参数
                if(StrUtil.isNotEmpty(dict.defaultValue())) {
                    fillDefaultValue(dataList, dict.defaultValue(), f.getName(), fillTextList);
                    return;
                }

                DictFeignServiceFacade dictServiceFacade = AppContextUtil.getBean(DictFeignServiceFacade.class);
                List attrList = (List) dictServiceFacade.querySysDataDictByCode(codeList.get(0));
                if(attrList!=null&& !attrList.isEmpty()) {
                    for (Object data : dataList) {
                        BeanWrapper beanWrapper = new BeanWrapperImpl(data);
                        Object fValue = beanWrapper.getPropertyValue(f.getName());
                        if(fValue instanceof Collection){
                            List<Object> fValueList = (List<Object>) fValue;
                            List<Object> fNameList = new ArrayList<>();
                            for (Object attr : attrList) {
                                BeanWrapper attrWrapper = new BeanWrapperImpl(attr);
                                for(Object obj:fValueList) {
                                    if ((attrWrapper.getPropertyValue(contrastText) + "").equals(obj + "")) {
                                        fNameList.add(attrWrapper.getPropertyValue(contrastFillTextList.get(0)));
                                        break;
                                    }
                                }
                            }
                            beanWrapper.setPropertyValue(fillTextList.get(0), fNameList);
                        }else {
                            for (Object attr : attrList) {
                                BeanWrapper attrWrapper = new BeanWrapperImpl(attr);
                                if ((attrWrapper.getPropertyValue(contrastText) + "").equals(beanWrapper.getPropertyValue(f.getName()) + "")) {
                                    for (int i = 0; i < fillTextList.size(); i++) {
                                        beanWrapper.setPropertyValue(fillTextList.get(i), attrWrapper.getPropertyValue(contrastFillTextList.get(i)));
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        });
    }


    /**
     * 装填默认设置值
     * @return
     */
    private static List fillDefaultValue(List dataList, String defaultValue, String fName, List<String> fillTextList){
        if(StrUtil.isBlank(defaultValue)) return dataList;
        String[] defaultArray = defaultValue.replaceAll("，",",").split(",");
        for (Object data : dataList) {
            BeanWrapper beanWrapper = new BeanWrapperImpl(data);
            Object fValue = beanWrapper.getPropertyValue(fName);
            if(fValue instanceof Collection){
                List<Object> fValueList = (List<Object>) fValue;
                List<Object> fNameList = new ArrayList<>();
                for (String str : defaultArray) {
                    String strValue = str.substring(0,str.indexOf("="));
                    String strName = str.substring(str.indexOf("=")+1);
                    for(Object obj:fValueList) {
                        if (strValue.equals(obj + "")) {
                            fNameList.add(strName);
                            break;
                        }
                    }
                }
                beanWrapper.setPropertyValue(fillTextList.get(0), fNameList);
            }else {
                for (String str : defaultArray) {
                    String strValue = str.substring(0,str.indexOf("="));
                    String strName = str.substring(str.indexOf("=")+1);
                    if (strValue.equals(beanWrapper.getPropertyValue(fName) + "")) {
                        for (int i = 0; i < fillTextList.size(); i++) {
                            beanWrapper.setPropertyValue(fillTextList.get(i), strName);
                        }
                        break;
                    }
                }
            }
        }
        return dataList;
    }



}
